home *** CD-ROM | disk | FTP | other *** search
- #include "SoundPlayer.h"
- #include <assertmb.h>
-
- #define min(a,b) (((a)<(b))?(a):(b))
-
- OSErr SoundPlayer::InitEntryList()
- {
- OSErr err = noErr;
-
- err = fReceiverList.Reallocate(kNumChannels);
- if(err == noErr){
- for(short z = 0;z<kNumChannels;z++){
- fReceiverList[z].receiver = NULL;
- fReceiverList[z].readBuffer = NULL;
- fReceiverList[z].curPlay = NULL;
- fReceiverList[z].obj = this;
- }
-
- for(short z = 0;z<kNumChannels;z++){
- fReceiverList[z].receiver = new SReceiver(_ReadProc, (long)&fReceiverList[z], _CancelProc, kBufferSize);
- err = fReceiverList[z].receiver->Initialize();
- if(err == noErr){
- fReceiverList[z].receiver->Start();
- }
- }
-
- }
-
- return err;
- }
-
-
- void SoundPlayer::CancelProc(Entry* entry,SSCompletionProc ioCompletion,long completionData)
- {
- (*ioCompletion)(completionData,userCanceledErr,0);
- }
-
-
- void SoundPlayer::DoRead(Entry* entry)
- {
- if(entry->curPlay != NULL){
- UInt32 sizeWants = entry->readLength - entry->readPos;
- UInt32 sizeHas = entry->curSize - entry->curPos;
- UInt32 thisRead = min(sizeWants,sizeHas);
-
- BlockMoveData(entry->curPlay + entry->curPos,((Ptr)entry->readBuffer) + entry->readPos,thisRead);
- entry->readPos += thisRead;
- entry->curPos += thisRead;
-
- if((entry->readPos == entry->readLength) || (entry->curPos == entry->curSize)){
- entry->readBuffer = NULL;
- if(entry->curPos == entry->curSize){
- if(entry->loopQ){
- entry->curPos = 0;
- }else{
- entry->curPlay = NULL;
- }
- }
- (*entry->readCompletion)(entry->readCompletionData,noErr,entry->readPos);
- }
- }
- }
-
-
- pascal OSErr SoundPlayer::_ReadProc(void* buffer,long length,long refCon,
- SSCompletionProc completion,long completionData)
- {
- Entry* entry = (Entry*)refCon;
- SoundPlayer* thisObj = (SoundPlayer*)entry->obj;
-
- thisObj->ReadProc(entry,buffer,length,completion,completionData);
-
- return noErr;
- }
-
-
- pascal void SoundPlayer::_CancelProc(long refCon,SSCompletionProc ioCompletion,long completionData)
- {
- Entry* entry = (Entry*)refCon;
- SoundPlayer* thisObj = (SoundPlayer*)entry->obj;
-
- thisObj->CancelProc(entry,ioCompletion,completionData);
- }
-
-
- void SoundPlayer::ReadProc(Entry* entry,void* buffer,long length,SSCompletionProc proc,long completionData)
- {
- assert(entry->readBuffer == NULL);
- entry->readBuffer = buffer;
- entry->readLength = length;
- entry->readCompletion = proc;
- entry->readCompletionData = completionData;
- entry->readPos = 0;
-
- DoRead(entry);
- }
-
-
- SoundPlayer::~SoundPlayer()
- {
- for(short z = 0;z<fReceiverList.Size();z++){
- delete fReceiverList[z].receiver;
- }
- }
-
-
- SoundPlayer::SoundPlayer(OSErr& err)
- {
- err = InitEntryList();
- }
-
-
- void SoundPlayer::PlaySnd(Handle lockedSndHandle,long length,Boolean loopQ)
- {
- Entry* cur = NULL;
-
- for(short z = 0;z<fReceiverList.Size();z++){
- if(fReceiverList[z].curPlay == NULL){
- if(fReceiverList[z].readBuffer != NULL){
- cur = &fReceiverList[z];
- break;
- }
- }
- }
-
- if(cur != NULL){
- SHeader* header;
- long offset;
-
- OSErr err = GetSoundHeaderOffset((SndListHandle)lockedSndHandle,&offset);
- assert(err == noErr);
- if(err == noErr){
- header = (SHeader*) ((*lockedSndHandle)+offset);
-
- cur->receiver->SetSHeader(*header);
-
- switch(header->std.encode){
- case stdSH:
- cur->curPlay = (Ptr)header->std.sampleArea;
- cur->curSize = header->std.length;
- break;
- case extSH:
- cur->curPlay = (Ptr)header->ext.sampleArea;
- cur->curSize = header->ext.numChannels * header->ext.numFrames * (header->ext.sampleSize/8);
- break;
- case cmpSH:
- cur->curPlay = (Ptr)header->cmp.sampleArea;
- cur->curSize = header->cmp.numChannels * header->cmp.numFrames * (header->cmp.packetSize/8);
- break;
- default:
- assert(false);
- break;
- }
- cur->curPos = 0;
- cur->loopQ = loopQ;
- DoRead(cur);
- }
- }
- }
-